00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef _global_store_hpp_
00021 #define _global_store_hpp_
00022
00023 #include <iostream>
00024 #include <ga.h>
00025 #include "gridpack/utilities/exception.hpp"
00026 #include "gridpack/parallel/communicator.hpp"
00027
00028 namespace gridpack {
00029 namespace parallel {
00030
00031
00032
00033
00034 template <typename _data_type >
00035 class GlobalStore {
00036 private:
00037 gridpack::parallel::Communicator p_comm;
00038 public:
00039
00040
00041
00042
00043
00044
00045 GlobalStore(const gridpack::parallel::Communicator &comm)
00046 : p_comm(comm)
00047 {
00048 p_begin = NULL;
00049 p_end = NULL;
00050 p_datasize = sizeof(_data_type);
00051 p_me = comm.rank();
00052 p_nprocs = comm.size();
00053 p_uploaded = false;
00054 }
00055
00056
00057
00058
00059 ~GlobalStore(void)
00060 {
00061
00062 if (p_uploaded) {
00063 GA_Destroy(p_GA);
00064 }
00065 if (p_begin != NULL) delete [] p_begin;
00066 if (p_end != NULL) delete [] p_end;
00067 }
00068
00069
00070
00071
00072
00073
00074 void addVector(const int idx, const std::vector<_data_type> &vec)
00075 {
00076 p_index.push_back(idx);
00077 p_data.push_back(vec);
00078 }
00079
00080
00081
00082
00083
00084 void upload()
00085 {
00086
00087
00088
00089 int max_idx = 0;
00090 int i;
00091 for (i=0; i<p_index.size(); i++) {
00092 if (p_index[i] < 0) {
00093 char buf[256];
00094 sprintf(buf,"Index %d less than zero in GlobalStore::upload on process %d\n",
00095 p_index[i],p_me);
00096 printf("%s",buf);
00097 throw gridpack::Exception(buf);
00098 }
00099 if (p_index[i] > max_idx) max_idx = p_index[i];
00100 }
00101 p_comm.max(&max_idx,1);
00102 p_numVecs = max_idx+1;
00103
00104
00105 int nsize = max_idx+1;
00106 p_begin = new int[nsize];
00107 p_end = new int[nsize];
00108 for (i=0; i<nsize; i++) {
00109 p_begin[i] = 0;
00110 p_end[i] = 0;
00111 }
00112
00113
00114
00115 for (i=0; i<p_index.size(); i++) {
00116 p_begin[p_index[i]] += 1;
00117 }
00118 p_comm.sum(p_begin,nsize);
00119 for (i=0; i<nsize; i++) {
00120 if (p_begin[i] > 1) {
00121 char buf[256];
00122 sprintf(buf,"Multiple vectors for index %d GlobalStore::upload on process %d\n",
00123 i,p_me);
00124 printf("%s",buf);
00125 throw gridpack::Exception(buf);
00126 }
00127 p_begin[i] = 0;
00128 }
00129
00130
00131
00132 for (i=0; i<p_index.size(); i++) {
00133 p_end[p_index[i]] = p_data[i].size();
00134 }
00135 p_comm.sum(p_end,nsize);
00136 p_begin[0] = 0;
00137 for (i=1; i<nsize; i++) {
00138 p_begin[i] = p_begin[i-1]+p_end[i-1];
00139 }
00140 int ndata = 0;
00141 for (i=0; i<nsize; i++) {
00142 ndata += p_end[i];
00143 p_end[i] = p_begin[i]+p_end[i];
00144 }
00145
00146 if (ndata < 1) {
00147 std::cout << "No data found for global store" << std::endl;
00148 return;
00149 }
00150
00151
00152 int one = 1;
00153 int GA_type = NGA_Register_type(p_datasize);
00154 p_GA = GA_Create_handle();
00155 GA_Set_data(p_GA, one, &ndata, GA_type);
00156 int GAgrp = p_comm.getGroup();
00157 GA_Set_pgroup(p_GA, GAgrp);
00158 GA_Allocate(p_GA);
00159
00160
00161 for (i=0; i<p_index.size(); i++) {
00162 int idx = p_index[i];
00163 int lo = p_begin[idx];
00164 int hi = p_end[idx]-1;
00165 NGA_Put(p_GA,&lo,&hi,&((p_data[i])[0]),&one);
00166 p_data[i].clear();
00167 }
00168 p_data.clear();
00169 p_index.clear();
00170 p_uploaded = true;
00171 GA_Pgroup_sync(GAgrp);
00172 }
00173
00174
00175
00176
00177
00178
00179 void getVector(const int idx, std::vector<_data_type> &vec)
00180 {
00181 if (idx < 0 || idx >= p_numVecs) {
00182 char buf[256];
00183 sprintf(buf,"Requested vector index %d in GlobalStore::getVector out of range on process %d\n",
00184 idx,p_me);
00185 printf("%s",buf);
00186 throw gridpack::Exception(buf);
00187 }
00188 int ld = 1;
00189 int lo = p_begin[idx];
00190 int hi = p_end[idx]-1;
00191 int size = p_end[idx]-p_begin[idx];
00192 _data_type *dbuf = new _data_type[size];
00193 NGA_Get(p_GA,&lo,&hi,dbuf,&ld);
00194
00195 vec.clear();
00196 for (int i=0; i<size; i++) {
00197 vec.push_back(dbuf[i]);
00198 }
00199 delete [] dbuf;
00200 };
00201
00202 private:
00203
00204 int *p_begin;
00205 int *p_end;
00206
00207
00208 std::vector<std::vector<_data_type> > p_data;
00209 std::vector<int> p_index;
00210
00211
00212 int p_GA;
00213
00214
00215
00216 int p_datasize;
00217 int p_me;
00218 int p_nprocs;
00219 int p_numVecs;
00220
00221
00222 bool p_uploaded;
00223 };
00224 }
00225 }
00226
00227 #endif
00228